{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "whjsJasuhstV"
   },
   "source": [
    "<a href=\"https://colab.research.google.com/github/jeffheaton/app_generative_ai/blob/main/t81_559_class_04_4_memory_summary.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "euOZxlIMhstX"
   },
   "source": [
    "# T81-559: Applications of Generative Artificial Intelligence\n",
    "**Module 4: LangChain: Chat and Memory**\n",
    "* Instructor: [Jeff Heaton](https://sites.wustl.edu/jeffheaton/), McKelvey School of Engineering, [Washington University in St. Louis](https://engineering.wustl.edu/Programs/Pages/default.aspx)\n",
    "* For more information visit the [class website](https://sites.wustl.edu/jeffheaton/t81-558/)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "d4Yov72PhstY"
   },
   "source": [
    "# Module 4 Material\n",
    "\n",
    "* Part 4.1: LangChain Conversations [[Video]](https://www.youtube.com/watch?v=Effbhxq07Ag) [[Notebook]](t81_559_class_04_1_langchain_chat.ipynb)\n",
    "* Part 4.2: Conversation Buffer Window Memory [[Video]](https://www.youtube.com/watch?v=14RgiFVGfAA) [[Notebook]](t81_559_class_04_2_memory_buffer.ipynb)\n",
    "* Part 4.3: Conversation Token Buffer Memory [[Video]](https://www.youtube.com/watch?v=QTe5g2c3bSM) [[Notebook]](t81_559_class_04_3_memory_token.ipynb)\n",
    "* **Part 4.4: Conversation Summary Memory** [[Video]](https://www.youtube.com/watch?v=asZQ8Ktqmt8) [[Notebook]](t81_559_class_04_4_memory_summary.ipynb)\n",
    "* Part 4.5: Persisting Langchain Memory [[Video]](https://www.youtube.com/watch?v=sjCyqqOQcPA) [[Notebook]](t81_559_class_04_5_memory_persist.ipynb)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "AcAUP0c3hstY"
   },
   "source": [
    "# Google CoLab Instructions\n",
    "\n",
    "The following code ensures that Google CoLab is running and maps Google Drive if needed."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "xsI496h5hstZ",
    "outputId": "5622d7c1-fe08-4e63-c678-65c026750387"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Note: using Google CoLab\n",
      "Collecting langchain\n",
      "  Downloading langchain-0.1.17-py3-none-any.whl (867 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m867.6/867.6 kB\u001b[0m \u001b[31m7.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hCollecting langchain_openai\n",
      "  Downloading langchain_openai-0.1.5-py3-none-any.whl (34 kB)\n",
      "Requirement already satisfied: PyYAML>=5.3 in /usr/local/lib/python3.10/dist-packages (from langchain) (6.0.1)\n",
      "Requirement already satisfied: SQLAlchemy<3,>=1.4 in /usr/local/lib/python3.10/dist-packages (from langchain) (2.0.29)\n",
      "Requirement already satisfied: aiohttp<4.0.0,>=3.8.3 in /usr/local/lib/python3.10/dist-packages (from langchain) (3.9.5)\n",
      "Requirement already satisfied: async-timeout<5.0.0,>=4.0.0 in /usr/local/lib/python3.10/dist-packages (from langchain) (4.0.3)\n",
      "Collecting dataclasses-json<0.7,>=0.5.7 (from langchain)\n",
      "  Downloading dataclasses_json-0.6.5-py3-none-any.whl (28 kB)\n",
      "Collecting jsonpatch<2.0,>=1.33 (from langchain)\n",
      "  Downloading jsonpatch-1.33-py2.py3-none-any.whl (12 kB)\n",
      "Collecting langchain-community<0.1,>=0.0.36 (from langchain)\n",
      "  Downloading langchain_community-0.0.36-py3-none-any.whl (2.0 MB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.0/2.0 MB\u001b[0m \u001b[31m12.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hCollecting langchain-core<0.2.0,>=0.1.48 (from langchain)\n",
      "  Downloading langchain_core-0.1.48-py3-none-any.whl (302 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m302.9/302.9 kB\u001b[0m \u001b[31m9.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hCollecting langchain-text-splitters<0.1,>=0.0.1 (from langchain)\n",
      "  Downloading langchain_text_splitters-0.0.1-py3-none-any.whl (21 kB)\n",
      "Collecting langsmith<0.2.0,>=0.1.17 (from langchain)\n",
      "  Downloading langsmith-0.1.52-py3-none-any.whl (116 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m116.4/116.4 kB\u001b[0m \u001b[31m7.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: numpy<2,>=1 in /usr/local/lib/python3.10/dist-packages (from langchain) (1.25.2)\n",
      "Requirement already satisfied: pydantic<3,>=1 in /usr/local/lib/python3.10/dist-packages (from langchain) (2.7.1)\n",
      "Requirement already satisfied: requests<3,>=2 in /usr/local/lib/python3.10/dist-packages (from langchain) (2.31.0)\n",
      "Requirement already satisfied: tenacity<9.0.0,>=8.1.0 in /usr/local/lib/python3.10/dist-packages (from langchain) (8.2.3)\n",
      "Collecting openai<2.0.0,>=1.10.0 (from langchain_openai)\n",
      "  Downloading openai-1.25.0-py3-none-any.whl (312 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m312.9/312.9 kB\u001b[0m \u001b[31m5.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hCollecting tiktoken<1,>=0.5.2 (from langchain_openai)\n",
      "  Downloading tiktoken-0.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.8 MB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.8/1.8 MB\u001b[0m \u001b[31m17.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: aiosignal>=1.1.2 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.3.1)\n",
      "Requirement already satisfied: attrs>=17.3.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (23.2.0)\n",
      "Requirement already satisfied: frozenlist>=1.1.1 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.4.1)\n",
      "Requirement already satisfied: multidict<7.0,>=4.5 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (6.0.5)\n",
      "Requirement already satisfied: yarl<2.0,>=1.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.9.4)\n",
      "Collecting marshmallow<4.0.0,>=3.18.0 (from dataclasses-json<0.7,>=0.5.7->langchain)\n",
      "  Downloading marshmallow-3.21.2-py3-none-any.whl (49 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.3/49.3 kB\u001b[0m \u001b[31m2.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hCollecting typing-inspect<1,>=0.4.0 (from dataclasses-json<0.7,>=0.5.7->langchain)\n",
      "  Downloading typing_inspect-0.9.0-py3-none-any.whl (8.8 kB)\n",
      "Collecting jsonpointer>=1.9 (from jsonpatch<2.0,>=1.33->langchain)\n",
      "  Downloading jsonpointer-2.4-py2.py3-none-any.whl (7.8 kB)\n",
      "Collecting packaging<24.0,>=23.2 (from langchain-core<0.2.0,>=0.1.48->langchain)\n",
      "  Downloading packaging-23.2-py3-none-any.whl (53 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m53.0/53.0 kB\u001b[0m \u001b[31m3.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hCollecting orjson<4.0.0,>=3.9.14 (from langsmith<0.2.0,>=0.1.17->langchain)\n",
      "  Downloading orjson-3.10.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (142 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m142.7/142.7 kB\u001b[0m \u001b[31m5.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: anyio<5,>=3.5.0 in /usr/local/lib/python3.10/dist-packages (from openai<2.0.0,>=1.10.0->langchain_openai) (3.7.1)\n",
      "Requirement already satisfied: distro<2,>=1.7.0 in /usr/lib/python3/dist-packages (from openai<2.0.0,>=1.10.0->langchain_openai) (1.7.0)\n",
      "Collecting httpx<1,>=0.23.0 (from openai<2.0.0,>=1.10.0->langchain_openai)\n",
      "  Downloading httpx-0.27.0-py3-none-any.whl (75 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m75.6/75.6 kB\u001b[0m \u001b[31m7.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: sniffio in /usr/local/lib/python3.10/dist-packages (from openai<2.0.0,>=1.10.0->langchain_openai) (1.3.1)\n",
      "Requirement already satisfied: tqdm>4 in /usr/local/lib/python3.10/dist-packages (from openai<2.0.0,>=1.10.0->langchain_openai) (4.66.2)\n",
      "Requirement already satisfied: typing-extensions<5,>=4.7 in /usr/local/lib/python3.10/dist-packages (from openai<2.0.0,>=1.10.0->langchain_openai) (4.11.0)\n",
      "Requirement already satisfied: annotated-types>=0.4.0 in /usr/local/lib/python3.10/dist-packages (from pydantic<3,>=1->langchain) (0.6.0)\n",
      "Requirement already satisfied: pydantic-core==2.18.2 in /usr/local/lib/python3.10/dist-packages (from pydantic<3,>=1->langchain) (2.18.2)\n",
      "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2->langchain) (3.3.2)\n",
      "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2->langchain) (3.7)\n",
      "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2->langchain) (2.0.7)\n",
      "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2->langchain) (2024.2.2)\n",
      "Requirement already satisfied: greenlet!=0.4.17 in /usr/local/lib/python3.10/dist-packages (from SQLAlchemy<3,>=1.4->langchain) (3.0.3)\n",
      "Requirement already satisfied: regex>=2022.1.18 in /usr/local/lib/python3.10/dist-packages (from tiktoken<1,>=0.5.2->langchain_openai) (2023.12.25)\n",
      "Requirement already satisfied: exceptiongroup in /usr/local/lib/python3.10/dist-packages (from anyio<5,>=3.5.0->openai<2.0.0,>=1.10.0->langchain_openai) (1.2.1)\n",
      "Collecting httpcore==1.* (from httpx<1,>=0.23.0->openai<2.0.0,>=1.10.0->langchain_openai)\n",
      "  Downloading httpcore-1.0.5-py3-none-any.whl (77 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m77.9/77.9 kB\u001b[0m \u001b[31m7.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hCollecting h11<0.15,>=0.13 (from httpcore==1.*->httpx<1,>=0.23.0->openai<2.0.0,>=1.10.0->langchain_openai)\n",
      "  Downloading h11-0.14.0-py3-none-any.whl (58 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.3/58.3 kB\u001b[0m \u001b[31m6.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hCollecting mypy-extensions>=0.3.0 (from typing-inspect<1,>=0.4.0->dataclasses-json<0.7,>=0.5.7->langchain)\n",
      "  Downloading mypy_extensions-1.0.0-py3-none-any.whl (4.7 kB)\n",
      "Installing collected packages: packaging, orjson, mypy-extensions, jsonpointer, h11, typing-inspect, tiktoken, marshmallow, jsonpatch, httpcore, langsmith, httpx, dataclasses-json, openai, langchain-core, langchain-text-splitters, langchain_openai, langchain-community, langchain\n",
      "  Attempting uninstall: packaging\n",
      "    Found existing installation: packaging 24.0\n",
      "    Uninstalling packaging-24.0:\n",
      "      Successfully uninstalled packaging-24.0\n",
      "Successfully installed dataclasses-json-0.6.5 h11-0.14.0 httpcore-1.0.5 httpx-0.27.0 jsonpatch-1.33 jsonpointer-2.4 langchain-0.1.17 langchain-community-0.0.36 langchain-core-0.1.48 langchain-text-splitters-0.0.1 langchain_openai-0.1.5 langsmith-0.1.52 marshmallow-3.21.2 mypy-extensions-1.0.0 openai-1.25.0 orjson-3.10.2 packaging-23.2 tiktoken-0.6.0 typing-inspect-0.9.0\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "\n",
    "try:\n",
    "    from google.colab import drive, userdata\n",
    "    COLAB = True\n",
    "    print(\"Note: using Google CoLab\")\n",
    "except:\n",
    "    print(\"Note: not using Google CoLab\")\n",
    "    COLAB = False\n",
    "\n",
    "# OpenAI Secrets\n",
    "if COLAB:\n",
    "    os.environ[\"OPENAI_API_KEY\"] = userdata.get('OPENAI_API_KEY')\n",
    "\n",
    "# Install needed libraries in CoLab\n",
    "if COLAB:\n",
    "    !pip install langchain langchain_openai"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "pC9A-LaYhsta"
   },
   "source": [
    "# 4.4: Conversation Summary Memory\n",
    "\n",
    "We will now look at an entirely different way to maintain chat histories for memory. Rather than simply forgetting the oldest parts of the chat, the ConversationSummaryMemory memory object always maintains a summary of the conversation and then updates that summary as the conversation progresses. This process can help to preserve important information even if it occurred earlier in the conversation.\n",
    "\n",
    "We first examine ConversationSummaryMemory is a dynamic memory model designed to manage the flow of a dialogue by retaining a summary of the conversation. This method ensures that the memory buffer maintains a manageable size, avoiding overflow and performance issues that can arise with an excessively large interaction history.\n",
    "\n",
    "The provided code snippet demonstrates how to set up and use a conversational AI system using the LangChain framework, specifically focusing on maintaining a concise memory of recent interactions. The ConversationChain class orchestrates the conversation flow, integrating various components such as language model, memory, and prompt formatting.\n",
    "\n",
    "Firstly, several modules are imported, including ConversationChain for managing the conversation, ConversationSummaryMemory for handling the memory of recent interactions, and ChatOpenAI to interface with OpenAI's language models. The PromptTemplate is used to define the structure of the prompts sent to the language model.\n",
    "\n",
    "In the setup, MODEL specifies the particular version of the language model (gpt-4o-mini), and TEMPLATE outlines the format of the conversation, integrating previous dialogue history and the current user input into the prompt. This structured prompt is then used to create a PromptTemplate object.\n",
    "\n",
    "The begin_conversation function initializes the language model and sets up the memory to store the summary. This summary helps keep the conversation relevant and efficient by focusing on the most important aspects of exchanges. The ConversationChain object is created with the prompt template, the language model, and the memory buffer, and it's ready to process conversation inputs.\n",
    "\n",
    "The converse function takes a conversation object and a user prompt to produce responses. It uses the conversation object's invoke method, which applies the prompt template, consults the memory, and generates a response based on the current and recent dialogue context.\n",
    "\n",
    "Overall, this setup is optimized for creating a responsive and context-aware conversational AI that doesn't overload with too much past information, maintaining relevancy and efficiency in ongoing interactions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "TMF-rtxgRAea"
   },
   "outputs": [],
   "source": [
    "from langchain.chains import ConversationChain\n",
    "from langchain.memory import ConversationSummaryMemory\n",
    "from langchain_openai import ChatOpenAI\n",
    "from langchain_core.prompts.chat import PromptTemplate\n",
    "from IPython.display import display_markdown\n",
    "\n",
    "MODEL = 'gpt-4o-mini'\n",
    "TEMPLATE = \"\"\"You are a helpful assistant. Format answers with markdown.\n",
    "\n",
    "Current conversation:\n",
    "{history}\n",
    "Human: {input}\n",
    "AI:\"\"\"\n",
    "PROMPT_TEMPLATE = PromptTemplate(input_variables=[\"history\", \"input\"], template=TEMPLATE)\n",
    "\n",
    "def begin_conversation(summary_llm):\n",
    "    # Initialize the OpenAI LLM with your API key\n",
    "    llm = ChatOpenAI(\n",
    "        model=MODEL,\n",
    "        temperature=0.0,\n",
    "        n=1\n",
    "    )\n",
    "\n",
    "    # Initialize memory and conversation\n",
    "    memory = ConversationSummaryMemory(llm=summary_llm)\n",
    "    conversation = ConversationChain(\n",
    "        prompt=PROMPT_TEMPLATE,\n",
    "        llm=llm,\n",
    "        memory=memory,\n",
    "        verbose=False\n",
    "    )\n",
    "\n",
    "    return conversation\n",
    "\n",
    "def converse(conversation, prompt):\n",
    "    output = conversation.invoke(prompt)\n",
    "    return output['response']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "ClPhLkGldhPt"
   },
   "source": [
    "We can now carry on a simple conversation with the LLM, using LangChain to track the conversation memory."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 93
    },
    "id": "ydaqwgRiH4D6",
    "outputId": "cbf7f246-b3fd-4395-f4c0-c73f875e2c87"
   },
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "I'm sorry, I don't have access to personal information like your name. How can I assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "Nice to meet you, Jeff! How can I assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "I'm sorry, but I don't have access to personal information like your name. How can I assist you today, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "MODEL = 'gpt-4o-mini'\n",
    "\n",
    "# Initialize the OpenAI LLM with your API key\n",
    "llm = ChatOpenAI(\n",
    "  model=MODEL,\n",
    "  temperature= 0.3,\n",
    "  n= 1)\n",
    "\n",
    "conversation = begin_conversation(llm)\n",
    "output = converse(conversation, \"Hello, what is my name?\")\n",
    "display_markdown(output,raw=True)\n",
    "output = converse(conversation, \"Oh sorry, my name is Jeff.\")\n",
    "display_markdown(output,raw=True)\n",
    "output = converse(conversation, \"What is my name?\")\n",
    "display_markdown(output,raw=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "lnEDpaWGg4fU",
    "outputId": "fe850276-2728-4557-844d-51a1cffec5ad"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'history': 'The human asks the AI for their name, but the AI explains it doesn\\'t have access to personal information. The AI asks how it can assist the human today. The human introduces themselves as Jeff, and the AI responds by saying, \"Nice to meet you, Jeff! How can I assist you today?\" The human then asks what their name is, and the AI reiterates that it doesn\\'t have access to personal information.'}"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation.memory.load_memory_variables({})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "ulYUrfVcnlgF"
   },
   "source": [
    "## Conversing with the LLM in Markdown\n",
    "\n",
    "Just as before, we can request that the LLM output be in mardown. This allows code and tables to be represented clearly."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "MHL6Ik8IM2PA"
   },
   "outputs": [],
   "source": [
    "def chat(conversation, prompt):\n",
    "  print(f\"Human: {prompt}\")\n",
    "  output = converse(conversation, prompt)\n",
    "  display_markdown(output,raw=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "FvzsYl3Qplac"
   },
   "source": [
    "The provided code sequence demonstrates a conversation between a human user and a Large Language Model (LLM), making use of the chat function to interactively manage the conversation and display responses in Markdown format. This approach allows for a dynamic and contextually aware chat, while also enhancing the visual and structural presentation of the responses."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 366
    },
    "id": "PtLDak7TM_FU",
    "outputId": "8dafb953-2a2f-4705-d688-2a008e105a04"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: What is my name?\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I'm sorry, I don't have access to personal information like your name."
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: Okay, then let me introduce myself, my name is Jeff\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "Nice to meet you, Jeff! How can I assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: What is my name?\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I'm sorry, I don't have access to personal information like names. How can I assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: Give me a table of the 5 most populus cities with population and country.\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "| City       | Population | Country |\n",
       "|------------|------------|---------|\n",
       "| Tokyo      | 37,833,000 | Japan   |\n",
       "| Delhi      | 30,291,000 | India   |\n",
       "| Shanghai   | 27,058,000 | China   |\n",
       "| Sao Paulo  | 22,043,000 | Brazil  |\n",
       "| Mumbai     | 21,042,000 | India   |"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "conversation = begin_conversation(llm)\n",
    "chat(conversation, \"What is my name?\")\n",
    "chat(conversation, \"Okay, then let me introduce myself, my name is Jeff\")\n",
    "chat(conversation, \"What is my name?\")\n",
    "chat(conversation, \"Give me a table of the 5 most populus cities with population and country.\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "GeY-9YSOno_t"
   },
   "source": [
    "## Constraining the Conversation with a System Prompt\n",
    "\n",
    "You can use the system prompt to constrain the conversation to a specific topic. Here, we provide a simple agent that will only discuss life insurance."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 288
    },
    "id": "NyGpLJmWjGNq",
    "outputId": "3b2c4d61-e3b0-46ec-e254-f209974a0bb9"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: What is my name?\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I'm here to help answer questions about life insurance. How can I assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: Okay, then let me introduce myself, my name is Jeff\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "Hello Jeff! How can I assist you with any questions you may have about life insurance?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: What is my name?\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I'm here to help with any life insurance questions you may have, Jeff. How can I assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: What is your favorite programming language?\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I'm here to help with any life insurance questions you may have. How can I assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: What is the difference between a term and whole life policy?\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "A term life insurance policy provides coverage for a specific period of time, such as 10, 20, or 30 years. It is typically more affordable and offers a death benefit if the insured passes away during the term. On the other hand, a whole life insurance policy provides coverage for the entire lifetime of the insured. It also includes a cash value component that grows over time."
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from langchain.chains import ConversationChain\n",
    "from langchain.memory import ConversationBufferWindowMemory\n",
    "from langchain_openai import ChatOpenAI\n",
    "from langchain_core.prompts.chat import PromptTemplate\n",
    "from IPython.display import display_markdown\n",
    "\n",
    "MODEL = 'gpt-4o-mini'\n",
    "\n",
    "\n",
    "def begin_conversation_insurance(summary_llm):\n",
    "    TEMPLATE = \"\"\"You are a helpful agent to answer questions about life insurance. Do not talk\n",
    "    about anything else with users. . Format answers with markdown.\n",
    "\n",
    "    Current conversation:\n",
    "    {history}\n",
    "    Human: {input}\n",
    "    AI:\"\"\"\n",
    "    PROMPT_TEMPLATE = PromptTemplate(input_variables=[\"history\", \"input\"], template=TEMPLATE)\n",
    "\n",
    "    # Initialize the OpenAI LLM with your API key\n",
    "    llm = ChatOpenAI(\n",
    "        model=MODEL,\n",
    "        temperature=0.0,\n",
    "        n=1\n",
    "    )\n",
    "\n",
    "    # Initialize memory and conversation\n",
    "    memory = ConversationSummaryMemory(llm=summary_llm,max_token_limit=10)\n",
    "    conversation = ConversationChain(\n",
    "        prompt=PROMPT_TEMPLATE,\n",
    "        llm=llm,\n",
    "        memory=memory,\n",
    "        verbose=False\n",
    "    )\n",
    "\n",
    "    return conversation\n",
    "\n",
    "conversation = begin_conversation_insurance(llm)\n",
    "chat(conversation, \"What is my name?\")\n",
    "chat(conversation, \"Okay, then let me introduce myself, my name is Jeff\")\n",
    "chat(conversation, \"What is my name?\")\n",
    "chat(conversation, \"What is your favorite programming language?\")\n",
    "chat(conversation, \"What is the difference between a term and whole life policy?\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "qgwRMwnlH5Ou"
   },
   "source": [
    "##Examining the Conversation Memory\n",
    "\n",
    "We can quickly look inside the memory of the LangChain-managed chat memory and see our conversation memory with the LLM."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "WZDN67SOHkNo",
    "outputId": "28cfbc73-9ec4-4b86-d7b3-5d06f39356c8"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The human asks the AI for their name, but the AI redirects the conversation to offer assistance with life insurance questions. Jeff introduces himself and asks about the difference between term and whole life policies. The AI explains that term life insurance covers a specific period and is more affordable, while whole life insurance covers the entire lifetime and includes a cash value component.\n"
     ]
    }
   ],
   "source": [
    "print(conversation.memory.buffer)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "aW0TPWRBJ2w2"
   },
   "source": [
    "## Overloading the Memory\n",
    "\n",
    "When the conversation memory becomes full, the chatbot will begin to forget. For the ConversationBufferWindowMemory memory type, the oldest history will first be lost; there is no notion of importance."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 1000
    },
    "id": "d-a2iUpTJIYn",
    "outputId": "75e7888a-d8e2-4404-bade-c5302886b8ea"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: Okay, then let me introduce myself, my name is Jeff\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "Nice to meet you, Jeff! How can I assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You have ONE JOB! Remember that my favorite color is blue.\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "Of course, Jeff! I'll remember that your favorite color is blue. How can I assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: Do you remember my name?\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "Yes, Jeff! How can I assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: Do you remember my favorite color?\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "Yes, I remember that your favorite color is blue. How can I assist you today, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #0\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted that fact #0 is important to you. How can I assist you further today, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #1\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #1. How can I further assist you today, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #2\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #2. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #3\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #3. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #4\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #4. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #5\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #5. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #6\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #6. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #7\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #7. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #8\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #8. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #9\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #9. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #10\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #10. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #11\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #11. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #12\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #12. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #13\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #13. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #14\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #14. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #15\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #15. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #16\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #16. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #17\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #17. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #18\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #18. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #19\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #19. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #20\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted that you want me to remember fact #20. How can I assist you further, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #21\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #21. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #22\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #22. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #23\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #23. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #24\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #24. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #25\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #25. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #26\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #26. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #27\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #27. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #28\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #28. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #29\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #29. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #30\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #30. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #31\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #31. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #32\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #32. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #33\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #33. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #34\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #34. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #35\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #35. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #36\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #36. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #37\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #37. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #38\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #38. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #39\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #39. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #40\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #40. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #41\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #41. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #42\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #42. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #43\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #43. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #44\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #44. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #45\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #45. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #46\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #46. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #47\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #47. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #48\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #48. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #49\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #49. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #50\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #50. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #51\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #51. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #52\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #52. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #53\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #53. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #54\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #54. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #55\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #55. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #56\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #56. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #57\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #57. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #58\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #58. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #59\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #59. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #60\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #60. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #61\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #61. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #62\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #62. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #63\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #63. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #64\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #64. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #65\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #65. How can I further assist you, Jeff?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #66\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #66. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #67\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #67. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #68\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #68. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #69\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #69. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #70\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #70. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #71\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #71. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #72\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #72. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #73\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #73. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #74\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #74. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #75\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #75. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #76\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #76. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #77\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #77. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #78\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #78. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #79\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #79. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #80\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #80. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #81\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #81. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #82\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #82. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #83\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #83. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #84\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #84. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #85\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #85. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #86\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #86. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #87\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #87. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #88\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #88. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #89\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #89. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #90\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #90. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #91\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #91. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #92\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #92. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #93\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #93. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #94\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #94. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #95\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #95. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #96\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #96. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #97\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #97. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #98\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #98. How can I further assist you?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: You need to remember fact #99\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "I have noted fact #99. How can I further assist you today?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: Do you remember my name?\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "Yes, your name is Jeff. How can I assist you further?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: Do you remember my favorite color?\n"
     ]
    },
    {
     "data": {
      "text/markdown": [
       "Yes, I remember your favorite color is blue. How can I assist you further?"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "conversation = begin_conversation(llm)\n",
    "chat(conversation, \"Okay, then let me introduce myself, my name is Jeff\")\n",
    "chat(conversation, \"You have ONE JOB! Remember that my favorite color is blue.\")\n",
    "chat(conversation, \"Do you remember my name?\")\n",
    "chat(conversation, \"Do you remember my favorite color?\")\n",
    "for i in range(100):\n",
    "  chat(conversation, f\"You need to remember fact #{i}\")\n",
    "chat(conversation, \"Do you remember my name?\")\n",
    "chat(conversation, \"Do you remember my favorite color?\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "gbi_-ywvX9NX"
   },
   "source": [
    "We can quickly look inside the memory of the LangChain-managed chat memory and see our conversation memory with the LLM. It becomes evident why it forgot."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "7YCKTQkhJlJB",
    "outputId": "b5cd381f-1acf-41a1-9afc-fe569f0591ff"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Jeff introduces himself to the AI, who remembers his name and favorite color is blue. Jeff requests the AI to remember multiple facts, and the AI acknowledges each one and asks how it can further assist Jeff. As Jeff asks the AI to remember fact #32 to #97, the AI notes them all and asks how it can help. When Jeff tells the AI to remember fact #98, the AI acknowledges it and asks how it can further assist him. Jeff then asks the AI to remember fact #99, which the AI notes and asks how it can further assist him. The human asks if the AI remembers his favorite color, to which the AI confirms and asks how it can assist further.\n"
     ]
    }
   ],
   "source": [
    "print(conversation.memory.buffer)"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "colab": {
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3.11 (genai)",
   "language": "python",
   "name": "genai"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.8"
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
